package password

import (
	"context"

	"gitee.com/go-course/go8/projects/devcloud/mcenter/apps/code"
	"gitee.com/go-course/go8/projects/devcloud/mcenter/apps/token"
	"gitee.com/go-course/go8/projects/devcloud/mcenter/apps/token/provider"
	"gitee.com/go-course/go8/projects/devcloud/mcenter/apps/user"
	"github.com/infraboard/mcube/app"
	"github.com/infraboard/mcube/exception"
	"github.com/infraboard/mcube/logger"
	"github.com/infraboard/mcube/logger/zap"
)

var (
	AUTH_FAILED = exception.NewUnauthorized("用户名获取密码不正确")
)

type issuer struct {
	user user.Service

	log logger.Logger
}

func (i *issuer) Init() error {
	i.user = app.GetInternalApp(user.AppName).(user.Service)
	i.log = zap.L().Named("issuer.password")
	return nil
}

func (i *issuer) GrantType() token.GRANT_TYPE {
	return token.GRANT_TYPE_PASSWORD
}

func (i *issuer) Validate(ctx context.Context, username, password string) (*user.User, error) {
	if username == "" || password == "" {
		return nil, AUTH_FAILED
	}

	// 检测用户的密码是否正确
	u, err := i.user.DescribeUser(ctx, user.NewDescriptUserRequestWithName(username))
	if err != nil {
		return nil, err
	}
	if err := u.Password.CheckPassword(password); err != nil {
		return nil, AUTH_FAILED
	}

	return u, nil
}

func (i *issuer) IssueToken(ctx context.Context, req *token.IssueTokenRequest) (*token.Token, error) {
	// 1. 校验
	u, err := i.Validate(ctx, req.Username, req.Password)
	if err != nil {
		return nil, err
	}

	// 2. 颁发Token
	tk := token.NewToken(req)
	tk.Domain = u.Spec.Domain
	tk.Username = u.Spec.Username
	tk.UserType = u.Spec.Type
	tk.UserId = u.Id
	return tk, nil
}

func (i *issuer) IssueCode(ctx context.Context, req *code.IssueCodeRequest) (*code.Code, error) {
	// 1. 校验
	_, err := i.Validate(ctx, req.Username, req.Password)
	if err != nil {
		return nil, err
	}

	// 2. 颁发Code, 生成一个6位随机数
	cd, err := code.NewCode(req)
	if err != nil {
		return nil, err
	}
	return cd, nil
}

func init() {
	provider.Registe(&issuer{})
}
